package cn.bonoon.kernel.web.models;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import cn.bonoon.kernel.menus.ChannelInfo;
import cn.bonoon.kernel.menus.DesInfo;
import cn.bonoon.kernel.menus.IModuleInfo;
import cn.bonoon.kernel.menus.IStyleGetter;
import cn.bonoon.kernel.menus.IStyleInfo;
import cn.bonoon.kernel.menus.MenuInfo;
import cn.bonoon.kernel.menus.TabInfo;
import cn.bonoon.kernel.security.PrivilegeChecker;
import cn.bonoon.kernel.support.IOperator;
import cn.bonoon.kernel.util.StringHelper;

/**
 * <pre>
 * 需要生成整个界面的框架信息，包括：用户信息、频道栏、菜单、头部、尾部等框架信息
 * </pre>
 * 
 * @author jackson
 * 
 */
public final class LayoutModel extends PanelModel {
	private final static String DEFAULT_LAYOUT_NAME = "lo";
	private final static String DEFAULT_LAYOUT_MASTER = "layout-admin.vm";
	private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E");

	private String styleKey = "default";
	private String menuTitle = "功能菜单";
	private String navigationTitle;
	private String descriptor;
	private String desHref;
	private String menuOnClick;

	private int desHeight;
	private StringBuilder eastWorkspace;
	private ContextMenuItem[] cmItems;
	private IStyleInfo styleInfo;

	private final String home;
	private final StringBuilder fastNavi;
	private final StringBuilder menuSpace = new StringBuilder();
	private final StringBuilder channelItems = new StringBuilder();
	private final StringBuilder menuItems = new StringBuilder();

	/**
	 * 初始化整个界面的样式，基础框架等！
	 * 
	 * @param title
	 *            导航位置信息
	 * @param module
	 *            子系统
	 * @param config
	 */
	public void initLayout(String title, IStyleGetter styleGetter) {
		navigationTitle = title;
		this.styleInfo = styleGetter.getStyle();
		DesInfo des = styleGetter.getDes();
		if (null != des) {
			this.desHeight = des.getHeight();
			if (des.isHref()) {
				this.desHref = des.getValue();
			} else {
				this.descriptor = des.getValue();
			}
		}
	}

	@Override
	public StandardModel execute(String view) {
		if (menuItems.length() > 0) {
			menuSpace.append("<div title='").append(menuTitle).append("' data-settings=\"zone:'west', split:true, iconClassname:'icon-computer'\" style='width:")
					.append(styleInfo.getMenuWidth()).append("px;'>");
			String south = buildSouth();
			if (null != south) {
				menuSpace.append("<div class='bupborderlayout' fit='true'>").append(south)
						.append("<div data-settings=\"zone:'center', border:false\" style='padding:0px;margin:0px;'>");
				initMenus(menuSpace, block);
				menuSpace.append("</div></div>");
			} else {
				initMenus(menuSpace, block);
			}
			menuSpace.append("</div>");
		}
		return super.execute(view);
	}

	private void initMenus(StringBuilder menuSpace, StringBuilder block) {
		menuSpace.append("<ul id='tree-sys-menus'>").append(menuItems).append("</ul>");
		if (null != cmItems && cmItems.length > 0) {
			block.append("jQuery('#cm-tree-sys-menus').__menu([");
			cmItems[0].parse(menuSpace, block);
			for (int i = 1; i < cmItems.length; i++) {
				cmItems[i].parse(menuSpace, block.append(','));
			}
			block.append(']');
			if (StringHelper.isNotEmpty(menuOnClick)) {
				block.append(",function(menuButton){").append(menuOnClick).append("});");
			} else {
				block.append(");");
			}
		} else if (StringHelper.isNotEmpty(menuOnClick)) {
			block.append("jQuery('#tree-sys-menus').__menu(function(menuButton){").append(menuOnClick).append("});");
		} else {
			block.append("jQuery('#tree-sys-menus').__menu();");
		}
	}

	public static class ContextMenuItem {
		private final String name;
		private final String event;
		private String icon;

		public ContextMenuItem(String name, String event) {
			this("", name, event);
		}

		public ContextMenuItem(String icon, String name, String event) {
			this.name = name;
			this.event = event;
			this.icon = icon;
		}

		void parse(StringBuilder cm, StringBuilder ev) {
			cm.append("<div data-settings=\"iconClassname:'").append(icon).append("'\">").append(name).append("</div>");
			ev.append("{name:'").append(name).append("',event:function(){").append(event).append("}}");
		}
	}

	/**
	 * <pre>
	 * 点击事件的处理
	 * </pre>
	 * 
	 * @param menuContextMenu
	 */
	public void menuContextMenu(ContextMenuItem... cmItems) {
		this.cmItems = cmItems;
	}

	public void setMenuOnClick(String menuOnClick) {
		this.menuOnClick = menuOnClick;
	}

	private String buildSouth() {
		if (StringHelper.isNotEmpty(desHref)) {
			return "<div data-settings=\"zone:'south', split:true, border:false\" style='height:" + desHeight + "px;' href='" + desHref + "' ></div>";
		}
		if (StringHelper.isNotEmpty(descriptor)) {
			return "<div data-settings=\"zone:'south', split:true, border:false\" style='height:" + desHeight + "px;' >" + descriptor + "</div>";
		}
		return null;
	}

	public LayoutModel(String mid, HttpServletRequest request, String home) {
		super(mid, request, DEFAULT_LAYOUT_MASTER);
		this.home = home;
		this.fastNavi = new StringBuilder();
		setModelName(DEFAULT_LAYOUT_NAME);
	}

	public void eastWorkspace(String title, String href, int width, boolean collapsed, StringBuilder east) {
		eastWorkspace = new StringBuilder("<div data-settings=\"zone:'east'\"");
		if (StringHelper.isNotEmpty(title)) {
			eastWorkspace.append(" title='").append(title);
		}
		if (StringHelper.isNotEmpty(href)) {
			eastWorkspace.append(" href='").append(href);
		}
		if (width < 100)
			width = 250;
		eastWorkspace.append("' id='eastWorkspace' style='width:").append(width).append("px;' collapsed='")
				.append(collapsed ? "true" : "false").append("'>");
		if (null != east) {
			eastWorkspace.append(east);
		}
		eastWorkspace.append("</div>");
	}

	public String getDay() {
		return sdf.format(new Date());
	}

	public StringBuilder getEastWorkspace() {
		return eastWorkspace;
	}

	public String getDescriptor() {
		return descriptor;
	}

	public IStyleInfo getStyle() {
		return styleInfo;
	}

	/**
	 * 可以追加菜单
	 */
	public void menuItem(StringBuilder item) {
		if (null != item) {
			this.menuItems.append(item);
		}
	}

	public void menuItem(StringBuilder item0, String item1) {
		this.menuItems.append(item0).append(item1);
	}

	public void menuItem(String item) {
		this.menuItems.append(item);
	}

	public void menuItem(String item0, String item1) {
		this.menuItems.append(item0).append(item1);
	}

	public void menuItem(String item0, String item1, String item2) {
		this.menuItems.append(item0).append(item1).append(item2);
	}

	public StringBuilder menuBuilder() {
		return menuItems;
	}

	public String getNavigationTitle() {
		return navigationTitle;
	}

	public LayoutModel setMenuTitle(String menuTitle) {
		if (StringHelper.isNotEmpty(menuTitle)) {
			this.menuTitle = menuTitle;
		}
		return this;
	}

	public String getDesHref() {
		return desHref;
	}

	public StringBuilder getFastNavi() {
		return fastNavi;
	}

	public String getHome() {
		return home;
	}

	public int getDesHeight() {
		return desHeight;
	}

	public String getStyleKey() {
		return styleKey;
	}

	public void setStyleKey(String styleKey) {
		if (StringHelper.isNotEmpty(styleKey)) {
			this.styleKey = styleKey;
		}
	}

	public StringBuilder getChannelItems() {
		return channelItems;
	}

	public void buildChannel(IModuleInfo module, IOperator user, PrivilegeChecker privilege, String selected) {
		List<ChannelInfo> cis = module.getChannels(user, privilege);
		
		// 返回界面，显示不同标题图片
		this.addObject("userName", user.getUsername());
		this.addObject("moduleName", module.getName());
		
		channelItems.append("<li");
		String channelClass = "";
		if (StringHelper.isEmpty(selected)) {
			if (cis.isEmpty()) {
				channelItems.append(" class='lastChannelSelected'");
			} else {
				channelItems.append(" class='channelSelected'");
				channelClass = " class='afterSelected'";
			}
		}
		channelItems.append("><a href='").append(module.getEndpoint()).append("'><span>首页</span></a></li>");
		int i = 0;
		for (ChannelInfo channel : cis) {
			i++;
			channelItems.append("<li");
			if (channel.selected(selected)) {
				if (i == cis.size()) {
					channelItems.append(" class='lastChannelSelected'");
				} else {
					channelItems.append(" class='channelSelected'");
					channelClass = " class='afterSelected'";
				}
			} else {
				channelItems.append(channelClass);
			}
			channelItems.append('>');
			// TODO 如果channel下没有定义访问的路径，则应该使用子菜单下第一个有访问权限的子菜单来显示
			channel.button(privilege, channelItems);
			channelItems.append("</li>");
		}
	}

	public void buildMenu(ChannelInfo channel, PrivilegeChecker privilege, String selected) {
		StringBuilder icon_menu = new StringBuilder("<style type='text/css'>");
		StringBuilder mi = menuHtml(channel.getMenus(), selected, privilege, icon_menu);
		if (null != mi && mi.length() > 0) {
			menuItems.append(mi);
		}
		// 如果是tabs则应该在频道的菜单最后面追加
		for (TabInfo tsi : channel.getTabs()) {
			if (privilege.hasPrivilege(tsi)) {
				menuItems.append("<li data-settings=\"");
				menuItems.append("iconClassname:'icon-menu'");//图标

				menuItems.append(",id:'").append(tsi.getId()).append("'");//id
				
				menuItems.append("\"><span>");
				if (tsi.selected(selected)) {
					tsi.button(menuItems, "menuSelected");
				} else {
					tsi.button(menuItems, "");
				}
				menuItems.append("</span></li>");
			}
		}
		this.addObject("icon_menu", icon_menu.append("</style>"));
	}

	private StringBuilder menuHtml(List<MenuInfo> menus, String sid, PrivilegeChecker privilege, StringBuilder icon_menu) {
		if (null == menus) {
			return null;
		}
		StringBuilder ul = new StringBuilder();

		for (MenuInfo menu : menus) {
			StringBuilder subul = menuHtml(menu.getMenus(), sid, privilege, icon_menu);

			String iconCls = menu.getIconCls();
			boolean bl_icon = StringHelper.isNotEmpty(iconCls);
			String menu_id = menu.getId();
			if (bl_icon) {
				icon_menu.append(".icon-menu-").append(menu_id).append("{background:url('").append(iconCls).append("') no-repeat; background-size:contain;}");
			}

			// 是否有操作的权限
			if (privilege.hasPrivilege(menu)) {
				// 是否应该设置为选中状态,如果选择的菜单ID相同
				boolean selected = menu.selected(sid);
				if (null != subul && subul.length() > 0) {
					// 有下级子菜单的情况
					ul.append("<li data-settings=\"");
					if (bl_icon){
						ul.append("iconClassname:'icon-menu-").append(menu_id).append("'");
					}else{
						ul.append("iconClassname:'icon-menus'");
					}

					ul.append(",id:'").append(menu_id).append("'");//id
					
					ul.append("\">");
					// 显示的文本内容
					button(ul, menu, selected).append("<ul>").append(subul).append("</ul>");
				} else {
					// 没有下级的子菜单的情况

					ul.append("<li data-settings=\"");
					if (bl_icon){
						ul.append("iconClassname:'icon-menu-").append(menu_id).append("'");
					}else{
						ul.append("iconClassname:'icon-menu'");
					}

					ul.append(",id:'").append(menu_id).append("'");//id
					
					ul.append("\">");
					
					// 显示的文本内容
					button(ul, menu, selected);
				}
				ul.append("</li>");
			} else if (null != subul) {
				// 有下级子菜单的情况
				// 功能显示该菜单,但不能对该菜单进行操作

				ul.append("<li data-settings=\"");
				
				if (bl_icon){
					ul.append("iconClassname:'icon-menu-").append(menu_id).append("'");
				}else{
					ul.append("iconClassname:'icon-menus'");
				}

				ul.append(",id:'").append(menu_id).append("'");//id
				
				ul.append("\"><span><a href='javascript:void(null);'>").append(menu.getName()).append("</a></span><ul>").append(subul).append("</ul></li>");
			} else {
				continue;
			}
		}
		return ul;
	}

	private StringBuilder button(StringBuilder a, MenuInfo menu, boolean selected) {
		a.append("<span>");
		if (selected) {
			menu.button(a, "menuSelected ");
		} else {
			menu.button(a, "");
		}
		return a.append("</span>");
	}

	public StringBuilder getMenuSpace() {
		return menuSpace;
	}
}
